new signal GtkCList::resize_column. don't draw invisible columns
authorLars Hamann <lars@gtk.org>
Wed, 7 Oct 1998 00:03:24 +0000 (00:03 +0000)
committerLars Hamann <lars@src.gnome.org>
Wed, 7 Oct 1998 00:03:24 +0000 (00:03 +0000)
Wed Oct  7 00:59:46 1998  Lars Hamann  <lars@gtk.org>

        * gtk/gtkclist.h: new signal GtkCList::resize_column.
        * gtk/gtkclist.c (draw_row): don't draw invisible columns
        (size_allocate_title_buttons) (size_allocate_columns):
        skip invisible columns
        (new_column_width): take min/max_width into account
        (gtk_clist_button_release) (gtk_clist_motion):
        changes due to changed new_column_width function
        (LIST_WIDTH): changed define to inline function.
        (real_resize_column): class function for resize_column signal
        (gtk_clist_motion): fixed autoscrolling for column resizes
        (gtk_clist_set_column_visibility): don't hide last visible column,
        changed visible arg to gboolean
        (gtk_clist_set_column_min_width)(gtk_clist_set_column_max_width):
        new functions : set min/max width of a column
        (gtk_clist_set_column_resizeable): new function : enable/disable
        column resize operations by mouse

        * gtk/gtkctree.c (draw_row): don't draw invisible columns
        (ctree_is_hot_spot): return FALSE if tree_column is invisible
        (draw_xor_line)  (draw_xor_rect): draw full rectangle/line if
        tree_column is invisible
        (gtk_ctree_find_all_by_row_data)
        (gtk_ctree_find_all_by_row_data_custom):  new function from
        Ronan Bourlier <ronan@radioss.com>. Returns a GList of all
        GtkCTreeNodes with row->data == data.

ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkclist.c
gtk/gtkclist.h
gtk/gtkctree.c
gtk/gtkctree.h

index 008b31755a86f356453b3ed0eaf085437b2d2804..cab5504abaac58c5897cededd56905c640ef8329 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+Wed Oct  7 00:59:46 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.h: new signal GtkCList::resize_column.
+       * gtk/gtkclist.c (draw_row): don't draw invisible columns
+       (size_allocate_title_buttons) (size_allocate_columns):
+       skip invisible columns
+       (new_column_width): take min/max_width into account 
+       (gtk_clist_button_release) (gtk_clist_motion):
+       changes due to changed new_column_width function
+       (LIST_WIDTH): changed define to inline function.
+       (real_resize_column): class function for resize_column signal
+       (gtk_clist_motion): fixed autoscrolling for column resizes
+       (gtk_clist_set_column_visibility): don't hide last visible column,
+       changed visible arg to gboolean
+       (gtk_clist_set_column_min_width)(gtk_clist_set_column_max_width):
+       new functions : set min/max width of a column
+       (gtk_clist_set_column_resizeable): new function : enable/disable
+       column resize operations by mouse
+
+       * gtk/gtkctree.c (draw_row): don't draw invisible columns
+       (ctree_is_hot_spot): return FALSE if tree_column is invisible
+       (draw_xor_line)  (draw_xor_rect): draw full rectangle/line if
+       tree_column is invisible
+       (gtk_ctree_find_all_by_row_data)
+       (gtk_ctree_find_all_by_row_data_custom):  new function from
+       Ronan Bourlier <ronan@radioss.com>. Returns a GList of all
+       GtkCTreeNodes with row->data == data.
+
 Tue Oct  6 14:05:00 1998  Tim Janik  <timj@gtk.org>
 
        * gtk/testgtk.c (cb_tree_destroy_event): use g_free to free g_malloced
index 008b31755a86f356453b3ed0eaf085437b2d2804..cab5504abaac58c5897cededd56905c640ef8329 100644 (file)
@@ -1,3 +1,31 @@
+Wed Oct  7 00:59:46 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.h: new signal GtkCList::resize_column.
+       * gtk/gtkclist.c (draw_row): don't draw invisible columns
+       (size_allocate_title_buttons) (size_allocate_columns):
+       skip invisible columns
+       (new_column_width): take min/max_width into account 
+       (gtk_clist_button_release) (gtk_clist_motion):
+       changes due to changed new_column_width function
+       (LIST_WIDTH): changed define to inline function.
+       (real_resize_column): class function for resize_column signal
+       (gtk_clist_motion): fixed autoscrolling for column resizes
+       (gtk_clist_set_column_visibility): don't hide last visible column,
+       changed visible arg to gboolean
+       (gtk_clist_set_column_min_width)(gtk_clist_set_column_max_width):
+       new functions : set min/max width of a column
+       (gtk_clist_set_column_resizeable): new function : enable/disable
+       column resize operations by mouse
+
+       * gtk/gtkctree.c (draw_row): don't draw invisible columns
+       (ctree_is_hot_spot): return FALSE if tree_column is invisible
+       (draw_xor_line)  (draw_xor_rect): draw full rectangle/line if
+       tree_column is invisible
+       (gtk_ctree_find_all_by_row_data)
+       (gtk_ctree_find_all_by_row_data_custom):  new function from
+       Ronan Bourlier <ronan@radioss.com>. Returns a GList of all
+       GtkCTreeNodes with row->data == data.
+
 Tue Oct  6 14:05:00 1998  Tim Janik  <timj@gtk.org>
 
        * gtk/testgtk.c (cb_tree_destroy_event): use g_free to free g_malloced
index 008b31755a86f356453b3ed0eaf085437b2d2804..cab5504abaac58c5897cededd56905c640ef8329 100644 (file)
@@ -1,3 +1,31 @@
+Wed Oct  7 00:59:46 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.h: new signal GtkCList::resize_column.
+       * gtk/gtkclist.c (draw_row): don't draw invisible columns
+       (size_allocate_title_buttons) (size_allocate_columns):
+       skip invisible columns
+       (new_column_width): take min/max_width into account 
+       (gtk_clist_button_release) (gtk_clist_motion):
+       changes due to changed new_column_width function
+       (LIST_WIDTH): changed define to inline function.
+       (real_resize_column): class function for resize_column signal
+       (gtk_clist_motion): fixed autoscrolling for column resizes
+       (gtk_clist_set_column_visibility): don't hide last visible column,
+       changed visible arg to gboolean
+       (gtk_clist_set_column_min_width)(gtk_clist_set_column_max_width):
+       new functions : set min/max width of a column
+       (gtk_clist_set_column_resizeable): new function : enable/disable
+       column resize operations by mouse
+
+       * gtk/gtkctree.c (draw_row): don't draw invisible columns
+       (ctree_is_hot_spot): return FALSE if tree_column is invisible
+       (draw_xor_line)  (draw_xor_rect): draw full rectangle/line if
+       tree_column is invisible
+       (gtk_ctree_find_all_by_row_data)
+       (gtk_ctree_find_all_by_row_data_custom):  new function from
+       Ronan Bourlier <ronan@radioss.com>. Returns a GList of all
+       GtkCTreeNodes with row->data == data.
+
 Tue Oct  6 14:05:00 1998  Tim Janik  <timj@gtk.org>
 
        * gtk/testgtk.c (cb_tree_destroy_event): use g_free to free g_malloced
index 008b31755a86f356453b3ed0eaf085437b2d2804..cab5504abaac58c5897cededd56905c640ef8329 100644 (file)
@@ -1,3 +1,31 @@
+Wed Oct  7 00:59:46 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.h: new signal GtkCList::resize_column.
+       * gtk/gtkclist.c (draw_row): don't draw invisible columns
+       (size_allocate_title_buttons) (size_allocate_columns):
+       skip invisible columns
+       (new_column_width): take min/max_width into account 
+       (gtk_clist_button_release) (gtk_clist_motion):
+       changes due to changed new_column_width function
+       (LIST_WIDTH): changed define to inline function.
+       (real_resize_column): class function for resize_column signal
+       (gtk_clist_motion): fixed autoscrolling for column resizes
+       (gtk_clist_set_column_visibility): don't hide last visible column,
+       changed visible arg to gboolean
+       (gtk_clist_set_column_min_width)(gtk_clist_set_column_max_width):
+       new functions : set min/max width of a column
+       (gtk_clist_set_column_resizeable): new function : enable/disable
+       column resize operations by mouse
+
+       * gtk/gtkctree.c (draw_row): don't draw invisible columns
+       (ctree_is_hot_spot): return FALSE if tree_column is invisible
+       (draw_xor_line)  (draw_xor_rect): draw full rectangle/line if
+       tree_column is invisible
+       (gtk_ctree_find_all_by_row_data)
+       (gtk_ctree_find_all_by_row_data_custom):  new function from
+       Ronan Bourlier <ronan@radioss.com>. Returns a GList of all
+       GtkCTreeNodes with row->data == data.
+
 Tue Oct  6 14:05:00 1998  Tim Janik  <timj@gtk.org>
 
        * gtk/testgtk.c (cb_tree_destroy_event): use g_free to free g_malloced
index 008b31755a86f356453b3ed0eaf085437b2d2804..cab5504abaac58c5897cededd56905c640ef8329 100644 (file)
@@ -1,3 +1,31 @@
+Wed Oct  7 00:59:46 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.h: new signal GtkCList::resize_column.
+       * gtk/gtkclist.c (draw_row): don't draw invisible columns
+       (size_allocate_title_buttons) (size_allocate_columns):
+       skip invisible columns
+       (new_column_width): take min/max_width into account 
+       (gtk_clist_button_release) (gtk_clist_motion):
+       changes due to changed new_column_width function
+       (LIST_WIDTH): changed define to inline function.
+       (real_resize_column): class function for resize_column signal
+       (gtk_clist_motion): fixed autoscrolling for column resizes
+       (gtk_clist_set_column_visibility): don't hide last visible column,
+       changed visible arg to gboolean
+       (gtk_clist_set_column_min_width)(gtk_clist_set_column_max_width):
+       new functions : set min/max width of a column
+       (gtk_clist_set_column_resizeable): new function : enable/disable
+       column resize operations by mouse
+
+       * gtk/gtkctree.c (draw_row): don't draw invisible columns
+       (ctree_is_hot_spot): return FALSE if tree_column is invisible
+       (draw_xor_line)  (draw_xor_rect): draw full rectangle/line if
+       tree_column is invisible
+       (gtk_ctree_find_all_by_row_data)
+       (gtk_ctree_find_all_by_row_data_custom):  new function from
+       Ronan Bourlier <ronan@radioss.com>. Returns a GList of all
+       GtkCTreeNodes with row->data == data.
+
 Tue Oct  6 14:05:00 1998  Tim Janik  <timj@gtk.org>
 
        * gtk/testgtk.c (cb_tree_destroy_event): use g_free to free g_malloced
index 008b31755a86f356453b3ed0eaf085437b2d2804..cab5504abaac58c5897cededd56905c640ef8329 100644 (file)
@@ -1,3 +1,31 @@
+Wed Oct  7 00:59:46 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.h: new signal GtkCList::resize_column.
+       * gtk/gtkclist.c (draw_row): don't draw invisible columns
+       (size_allocate_title_buttons) (size_allocate_columns):
+       skip invisible columns
+       (new_column_width): take min/max_width into account 
+       (gtk_clist_button_release) (gtk_clist_motion):
+       changes due to changed new_column_width function
+       (LIST_WIDTH): changed define to inline function.
+       (real_resize_column): class function for resize_column signal
+       (gtk_clist_motion): fixed autoscrolling for column resizes
+       (gtk_clist_set_column_visibility): don't hide last visible column,
+       changed visible arg to gboolean
+       (gtk_clist_set_column_min_width)(gtk_clist_set_column_max_width):
+       new functions : set min/max width of a column
+       (gtk_clist_set_column_resizeable): new function : enable/disable
+       column resize operations by mouse
+
+       * gtk/gtkctree.c (draw_row): don't draw invisible columns
+       (ctree_is_hot_spot): return FALSE if tree_column is invisible
+       (draw_xor_line)  (draw_xor_rect): draw full rectangle/line if
+       tree_column is invisible
+       (gtk_ctree_find_all_by_row_data)
+       (gtk_ctree_find_all_by_row_data_custom):  new function from
+       Ronan Bourlier <ronan@radioss.com>. Returns a GList of all
+       GtkCTreeNodes with row->data == data.
+
 Tue Oct  6 14:05:00 1998  Tim Janik  <timj@gtk.org>
 
        * gtk/testgtk.c (cb_tree_destroy_event): use g_free to free g_malloced
index 008b31755a86f356453b3ed0eaf085437b2d2804..cab5504abaac58c5897cededd56905c640ef8329 100644 (file)
@@ -1,3 +1,31 @@
+Wed Oct  7 00:59:46 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.h: new signal GtkCList::resize_column.
+       * gtk/gtkclist.c (draw_row): don't draw invisible columns
+       (size_allocate_title_buttons) (size_allocate_columns):
+       skip invisible columns
+       (new_column_width): take min/max_width into account 
+       (gtk_clist_button_release) (gtk_clist_motion):
+       changes due to changed new_column_width function
+       (LIST_WIDTH): changed define to inline function.
+       (real_resize_column): class function for resize_column signal
+       (gtk_clist_motion): fixed autoscrolling for column resizes
+       (gtk_clist_set_column_visibility): don't hide last visible column,
+       changed visible arg to gboolean
+       (gtk_clist_set_column_min_width)(gtk_clist_set_column_max_width):
+       new functions : set min/max width of a column
+       (gtk_clist_set_column_resizeable): new function : enable/disable
+       column resize operations by mouse
+
+       * gtk/gtkctree.c (draw_row): don't draw invisible columns
+       (ctree_is_hot_spot): return FALSE if tree_column is invisible
+       (draw_xor_line)  (draw_xor_rect): draw full rectangle/line if
+       tree_column is invisible
+       (gtk_ctree_find_all_by_row_data)
+       (gtk_ctree_find_all_by_row_data_custom):  new function from
+       Ronan Bourlier <ronan@radioss.com>. Returns a GList of all
+       GtkCTreeNodes with row->data == data.
+
 Tue Oct  6 14:05:00 1998  Tim Janik  <timj@gtk.org>
 
        * gtk/testgtk.c (cb_tree_destroy_event): use g_free to free g_malloced
index 182afedd4ba0da2e1113ce954e1fc31fdf513689..1bbd24054082936701d1693243b32ecb7d211926 100644 (file)
@@ -95,10 +95,22 @@ COLUMN_FROM_XPIXEL (GtkCList * clist,
 #define LIST_HEIGHT(clist)         (((clist)->row_height * ((clist)->rows)) + \
                                    (CELL_SPACING * ((clist)->rows + 1)))
 
+
 /* returns the total width of the list */
-#define LIST_WIDTH(clist)          ((clist)->column[(clist)->columns - 1].area.x + \
-                                   (clist)->column[(clist)->columns - 1].area.width + \
-                                   COLUMN_INSET + CELL_SPACING)
+static inline gint
+LIST_WIDTH (GtkCList * clist) 
+{
+  gint last_column;
+
+  for (last_column = clist->columns - 1;
+       last_column >= 0 && !clist->column[last_column].visible; last_column--);
+
+  if (last_column >= 0)
+    return (clist->column[last_column].area.x +
+           clist->column[last_column].area.width +
+           COLUMN_INSET + CELL_SPACING);
+  return 0;
+}
 
 
 #define GTK_CLIST_CLASS_FW(_widget_) GTK_CLIST_CLASS (GTK_OBJECT (_widget_)->klass)
@@ -110,6 +122,7 @@ enum
   SELECT_ROW,
   UNSELECT_ROW,
   CLICK_COLUMN,
+  RESIZE_COLUMN,
   TOGGLE_FOCUS_ROW,
   SELECT_ALL,
   UNSELECT_ALL,
@@ -256,8 +269,10 @@ static void resync_selection (GtkCList *clist,
 static void draw_xor_line (GtkCList * clist);
 static gint new_column_width (GtkCList * clist,
                              gint column,
-                             gint * x,
-                             gint * visible);
+                             gint * x);
+static void real_resize_column (GtkCList * clist,
+                               gint column,
+                               gint width);
 static void resize_column (GtkCList * clist,
                           gint column,
                           gint width);
@@ -427,6 +442,13 @@ gtk_clist_class_init (GtkCListClass * klass)
                    GTK_SIGNAL_OFFSET (GtkCListClass, click_column),
                    gtk_marshal_NONE__INT,
                    GTK_TYPE_NONE, 1, GTK_TYPE_INT);
+  clist_signals[RESIZE_COLUMN] =
+    gtk_signal_new ("resize_column",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkCListClass, resize_column),
+                   gtk_marshal_NONE__INT_INT,
+                   GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
 
   clist_signals[TOGGLE_FOCUS_ROW] =
     gtk_signal_new ("toggle_focus_row",
@@ -541,6 +563,7 @@ gtk_clist_class_init (GtkCListClass * klass)
   klass->resync_selection = resync_selection;
   klass->selection_find = selection_find;
   klass->click_column = NULL;
+  klass->resize_column = real_resize_column;
   klass->draw_row = draw_row;
   klass->insert_row = real_insert_row;
   klass->remove_row = real_remove_row;
@@ -1010,20 +1033,99 @@ gtk_clist_column_titles_hide (GtkCList * clist)
 }
 
 void
-gtk_clist_set_column_visibility (GtkCList * clist, gint column, gint visible)
+gtk_clist_set_column_visibility (GtkCList *clist,
+                                gint      column,
+                                gboolean  visible)
 {
   g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
     return;
+  if (clist->column[column].visible == visible)
+    return;
 
-  if (clist->column[column].visible && !visible)
-    gtk_widget_hide (clist->column[column].button);
-  else if (!clist->column[column].visible && visible)
+  /* don't hide last visible column */
+  if (!visible)
+    {
+      gint i;
+      gint vis_columns = 0;
+
+      for (i = 0, vis_columns = 0; i < clist->columns && vis_columns < 2; i++)
+       if (clist->column[i].visible)
+         vis_columns++;
+
+      if (vis_columns < 2)
+       return;
+    }
+
+  clist->column[column].visible = visible;
+  if (visible)
     gtk_widget_show (clist->column[column].button);
+  else
+    gtk_widget_hide (clist->column[column].button);
+}
 
-  clist->column[column].visible = visible ? TRUE : FALSE;
+void
+gtk_clist_set_column_resizeable (GtkCList *clist,
+                                gint      column,
+                                gint      resizeable)
+{
+  g_return_if_fail (clist != NULL);
+  g_return_if_fail (GTK_IS_CLIST (clist));
+
+  if (column < 0 || column >= clist->columns)
+    return;
+  if (clist->column[column].resizeable == resizeable)
+    return;
+
+  clist->column[column].resizeable = resizeable;
+}
+
+void
+gtk_clist_set_column_min_width (GtkCList *clist,
+                               gint      column,
+                               gint      min_width)
+{
+  g_return_if_fail (clist != NULL);
+  g_return_if_fail (GTK_IS_CLIST (clist));
+
+  if (column < 0 || column >= clist->columns)
+    return;
+  if (clist->column[column].min_width == min_width)
+    return;
+
+  if (clist->column[column].max_width >= 0  &&
+      clist->column[column].max_width < min_width)
+    clist->column[column].min_width = clist->column[column].max_width;
+  else
+    clist->column[column].min_width = min_width;
+
+  if (clist->column[column].area.width < clist->column[column].min_width)
+    gtk_clist_set_column_width (clist, column,clist->column[column].min_width);
+}
+
+void
+gtk_clist_set_column_max_width (GtkCList * clist,
+                               gint column,
+                               gint max_width)
+{
+  g_return_if_fail (clist != NULL);
+  g_return_if_fail (GTK_IS_CLIST (clist));
+
+  if (column < 0 || column >= clist->columns)
+    return;
+  if (clist->column[column].max_width == max_width)
+    return;
+
+  if (clist->column[column].min_width >= 0 && max_width >= 0 &&
+      clist->column[column].min_width > max_width)
+    clist->column[column].max_width = clist->column[column].min_width;
+  else
+    clist->column[column].max_width = max_width;
+  
+  if (clist->column[column].area.width > clist->column[column].max_width)
+    gtk_clist_set_column_width (clist, column,clist->column[column].max_width);
 }
 
 void
@@ -1039,7 +1141,8 @@ gtk_clist_column_title_active (GtkCList * clist,
   if (!GTK_WIDGET_SENSITIVE (clist->column[column].button) ||
       !GTK_WIDGET_CAN_FOCUS (clist->column[column].button))
     {
-      GTK_WIDGET_SET_FLAGS (clist->column[column].button, GTK_SENSITIVE | GTK_CAN_FOCUS);
+      GTK_WIDGET_SET_FLAGS (clist->column[column].button,
+                           GTK_SENSITIVE | GTK_CAN_FOCUS);
       if (GTK_WIDGET_VISIBLE (clist))
        gtk_widget_queue_draw (clist->column[column].button);
     }
@@ -1243,10 +1346,10 @@ gtk_clist_set_column_justification (GtkCList * clist,
     draw_rows (clist, NULL);
 }
 
-void
-gtk_clist_set_column_width (GtkCList * clist,
-                           gint column,
-                           gint width)
+static void
+real_resize_column (GtkCList * clist,
+                   gint column,
+                   gint width)
 {
   g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
@@ -1254,6 +1357,12 @@ gtk_clist_set_column_width (GtkCList * clist,
   if (column < 0 || column >= clist->columns)
     return;
 
+  if (width < MAX (COLUMN_MIN_WIDTH, clist->column[column].min_width))
+    width = MAX (COLUMN_MIN_WIDTH, clist->column[column].min_width);
+  if (clist->column[column].max_width >= 0 &&
+      width > clist->column[column].max_width)
+    width = clist->column[column].max_width;
+  
   clist->column[column].width = width;
   clist->column[column].width_set = TRUE;
 
@@ -1271,6 +1380,21 @@ gtk_clist_set_column_width (GtkCList * clist,
     }
 }
 
+void
+gtk_clist_set_column_width (GtkCList * clist,
+                           gint column,
+                           gint width)
+{
+  g_return_if_fail (clist != NULL);
+  g_return_if_fail (GTK_IS_CLIST (clist));
+
+  if (column < 0 || column >= clist->columns)
+    return;
+
+  gtk_signal_emit (GTK_OBJECT (clist), clist_signals[RESIZE_COLUMN],
+                  column, width);
+}
+
 void
 gtk_clist_set_row_height (GtkCList * clist,
                          gint height)
@@ -2869,7 +2993,8 @@ gtk_clist_button_press (GtkWidget * widget,
 
   /* press on resize windows */
   for (i = 0; i < clist->columns; i++)
-    if (clist->column[i].window && event->window == clist->column[i].window)
+    if (clist->column[i].resizeable && clist->column[i].window &&
+       event->window == clist->column[i].window)
       {
        gdk_pointer_grab (clist->column[i].window, FALSE,
                          GDK_POINTER_MOTION_HINT_MASK |
@@ -2892,7 +3017,6 @@ gtk_clist_button_press (GtkWidget * widget,
 
        return FALSE;
       }
-
   return FALSE;
 }
 
@@ -2915,18 +3039,19 @@ gtk_clist_button_release (GtkWidget * widget,
   /* release on resize windows */
   if (GTK_CLIST_IN_DRAG (clist))
     {
-      gint i, x, width, visible;
+      gint width;
+      gint x;
+      gint i;
 
       i = clist->drag_pos;
       clist->drag_pos = -1;
+
       GTK_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG);
       gtk_widget_get_pointer (widget, &x, NULL);
-
-      width = new_column_width (clist, i, &x, &visible);
       gtk_grab_remove (widget);
       gdk_pointer_ungrab (event->time);
 
-      if (visible)
+      if (clist->x_drag >= 0)
        draw_xor_line (clist);
 
       if (GTK_CLIST_ADD_MODE (clist))
@@ -2936,6 +3061,7 @@ gtk_clist_button_release (GtkWidget * widget,
          gdk_gc_set_dashes (clist->xor_gc, 0, "\4\4", 2);
        }
 
+      width = new_column_width (clist, i, &x);
       resize_column (clist, i, width);
       return FALSE;
     }
@@ -3076,16 +3202,15 @@ gtk_clist_motion (GtkWidget * widget,
                  GdkEventMotion * event)
 {
   GtkCList *clist;
-  gint x, y, visible;
+  gint x;
+  gint y;
   gint row;
   gint new_width;
-  static gint cc =0;
 
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
 
   clist = GTK_CLIST (widget);
-  cc++;
   if (!(gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)))
     return FALSE;
 
@@ -3095,35 +3220,40 @@ gtk_clist_motion (GtkWidget * widget,
        gtk_widget_get_pointer (widget, &x, NULL);
       else
        x = event->x;
-
-      new_width = new_column_width (clist, clist->drag_pos, &x, &visible);
-      /* Welcome to my hack! I'm going to use a value of x_drag = -99999
-       * to indicate that the xor line is already invisible */
       
-      if (!visible && clist->x_drag != -99999)
+      new_width = new_column_width (clist, clist->drag_pos, &x);
+      if (x != clist->x_drag)
        {
-         draw_xor_line (clist);
-         clist->x_drag = -99999;
-       }
-
-      if (x != clist->x_drag && visible)
-       {
-         if (clist->x_drag != -99999)
+         /* x_drag < 0 indicates that the xor line is already invisible */
+         if (clist->x_drag >= 0)
            draw_xor_line (clist);
 
          clist->x_drag = x;
-         draw_xor_line (clist);
+
+         if (clist->x_drag >= 0)
+           draw_xor_line (clist);
        }
 
-      if (new_width <= COLUMN_MIN_WIDTH + 1)
+      if (new_width <= MAX (COLUMN_MIN_WIDTH + 1,
+                           clist->column[clist->drag_pos].min_width + 1))
        {
-         if (COLUMN_LEFT_XPIXEL (clist, clist->drag_pos) && x < 0)
+         if (COLUMN_LEFT_XPIXEL (clist, clist->drag_pos) < 0 && x < 0)
            gtk_clist_moveto (clist, -1, clist->drag_pos, 0, 0);
          return FALSE;
        }
+      if (clist->column[clist->drag_pos].max_width >= COLUMN_MIN_WIDTH &&
+         new_width >= clist->column[clist->drag_pos].max_width)
+       {
+         if (COLUMN_LEFT_XPIXEL (clist, clist->drag_pos) + new_width >
+             clist->clist_window_width && x < 0)
+           move_horizontal (clist,
+                            COLUMN_LEFT_XPIXEL (clist, clist->drag_pos) +
+                            new_width - clist->clist_window_width +
+                            COLUMN_INSET + CELL_SPACING);
+         return FALSE;
+       }
     }
 
-      
   if (event->is_hint || event->window != clist->clist_window)
     gdk_window_get_pointer (clist->clist_window, &x, &y, NULL);
 
@@ -3237,9 +3367,11 @@ gtk_clist_size_request (GtkWidget * widget,
     for (i = 0; i < clist->columns; i++)
       if (clist->column[i].button)
        {
-         gtk_widget_size_request (clist->column[i].button, &clist->column[i].button->requisition);
-         clist->column_title_area.height = MAX (clist->column_title_area.height,
-                                                clist->column[i].button->requisition.height);
+         gtk_widget_size_request (clist->column[i].button,
+                                  &clist->column[i].button->requisition);
+         clist->column_title_area.height =
+           MAX (clist->column_title_area.height,
+                clist->column[i].button->requisition.height);
        }
   requisition->height += clist->column_title_area.height;
 
@@ -3247,9 +3379,11 @@ gtk_clist_size_request (GtkWidget * widget,
   if ((clist->vscrollbar_policy == GTK_POLICY_AUTOMATIC) ||
       GTK_WIDGET_VISIBLE (clist->vscrollbar))
     {
-      gtk_widget_size_request (clist->vscrollbar, &clist->vscrollbar->requisition);
+      gtk_widget_size_request (clist->vscrollbar,
+                              &clist->vscrollbar->requisition);
 
-      requisition->width += clist->vscrollbar->requisition.width + SCROLLBAR_SPACING (clist);
+      requisition->width += (clist->vscrollbar->requisition.width +
+                            SCROLLBAR_SPACING (clist));
       requisition->height = MAX (requisition->height,
                                 clist->vscrollbar->requisition.height);
     }
@@ -3258,19 +3392,21 @@ gtk_clist_size_request (GtkWidget * widget,
   if ((clist->hscrollbar_policy == GTK_POLICY_AUTOMATIC) ||
       GTK_WIDGET_VISIBLE (clist->hscrollbar))
     {
-      gtk_widget_size_request (clist->hscrollbar, &clist->hscrollbar->requisition);
+      gtk_widget_size_request (clist->hscrollbar,
+                              &clist->hscrollbar->requisition);
 
-      requisition->height += clist->hscrollbar->requisition.height + SCROLLBAR_SPACING (clist);
+      requisition->height += (clist->hscrollbar->requisition.height +
+                             SCROLLBAR_SPACING (clist));
       requisition->width = MAX (clist->hscrollbar->requisition.width, 
                                requisition->width - 
                                clist->vscrollbar->requisition.width);
 
     }
 
-  requisition->width += widget->style->klass->xthickness * 2 +
-    GTK_CONTAINER (widget)->border_width * 2;
-  requisition->height += widget->style->klass->ythickness * 2 +
-    GTK_CONTAINER (widget)->border_width * 2;
+  requisition->width += (widget->style->klass->xthickness * 2 +
+                        GTK_CONTAINER (widget)->border_width * 2);
+  requisition->height += (widget->style->klass->ythickness * 2 +
+                         GTK_CONTAINER (widget)->border_width * 2);
 }
 
 static void
@@ -3281,6 +3417,7 @@ gtk_clist_size_allocate (GtkWidget * widget,
   GtkAllocation clist_allocation;
   GtkAllocation child_allocation;
   gint i, vscrollbar_vis, hscrollbar_vis;
+  gint border_width;
 
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
@@ -3288,14 +3425,15 @@ gtk_clist_size_allocate (GtkWidget * widget,
 
   clist = GTK_CLIST (widget);
   widget->allocation = *allocation;
+  border_width = GTK_CONTAINER (widget)->border_width;
 
   if (GTK_WIDGET_REALIZED (widget))
     {
       gdk_window_move_resize (widget->window,
-                             allocation->x + GTK_CONTAINER (widget)->border_width,
-                             allocation->y + GTK_CONTAINER (widget)->border_width,
-                             allocation->width - GTK_CONTAINER (widget)->border_width * 2,
-                             allocation->height - GTK_CONTAINER (widget)->border_width * 2);
+                             allocation->x + border_width,
+                             allocation->y + border_width,
+                             allocation->width - border_width * 2,
+                             allocation->height - border_width * 2);
     }
 
   /* use internal allocation structure for all the math
@@ -3304,19 +3442,21 @@ gtk_clist_size_allocate (GtkWidget * widget,
   clist->internal_allocation.x = 0;
   clist->internal_allocation.y = 0;
   clist->internal_allocation.width = MAX (1, allocation->width -
-    GTK_CONTAINER (widget)->border_width * 2);
+                                         border_width * 2);
   clist->internal_allocation.height = MAX (1, allocation->height -
-    GTK_CONTAINER (widget)->border_width * 2);
+                                          border_width * 2);
        
   /* allocate clist window assuming no scrollbars */
-  clist_allocation.x = clist->internal_allocation.x + widget->style->klass->xthickness;
-  clist_allocation.y = clist->internal_allocation.y + widget->style->klass->ythickness +
-    clist->column_title_area.height;
+  clist_allocation.x = (clist->internal_allocation.x +
+                       widget->style->klass->xthickness);
+  clist_allocation.y = (clist->internal_allocation.y +
+                       widget->style->klass->ythickness +
+                       clist->column_title_area.height);
   clist_allocation.width = MAX (1, clist->internal_allocation.width - 
-    (2 * widget->style->klass->xthickness));
+                               (2 * widget->style->klass->xthickness));
   clist_allocation.height = MAX (1, clist->internal_allocation.height -
-    (2 * widget->style->klass->ythickness) -
-    clist->column_title_area.height);
+                                (2 * widget->style->klass->ythickness) -
+                                clist->column_title_area.height);
   
   /* 
    * here's where we decide to show/not show the scrollbars
@@ -3331,32 +3471,26 @@ gtk_clist_size_allocate (GtkWidget * widget,
        {
          vscrollbar_vis = 0;
        }
-      else
+      else if (!vscrollbar_vis)
        {
-         if (!vscrollbar_vis)
-           {
-             vscrollbar_vis = 1;
-             clist_allocation.width = MAX (1, clist_allocation.width - 
-                (clist->vscrollbar->requisition.width +
-                SCROLLBAR_SPACING (clist)));
-           }  
-       }
+         vscrollbar_vis = 1;
+         clist_allocation.width = MAX (1, clist_allocation.width - 
+                                       (clist->vscrollbar->requisition.width +
+                                        SCROLLBAR_SPACING (clist)));
+       }  
       
       if (LIST_WIDTH (clist) <= clist_allocation.width &&
          clist->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
        {
          hscrollbar_vis = 0;
        }
-      else
+      else if (!hscrollbar_vis)
        {
-         if (!hscrollbar_vis)
-           {
-             hscrollbar_vis = 1;
-             clist_allocation.height = MAX (1, clist_allocation.height - 
-               (clist->hscrollbar->requisition.height +
-                SCROLLBAR_SPACING (clist)));
-           }  
-       }
+         hscrollbar_vis = 1;
+         clist_allocation.height = MAX (1, clist_allocation.height - 
+                                        (clist->hscrollbar->requisition.height
+                                         + SCROLLBAR_SPACING (clist)));
+       }  
     }
   
   clist->clist_window_width = clist_allocation.width;
@@ -3397,14 +3531,15 @@ gtk_clist_size_allocate (GtkWidget * widget,
       if (!GTK_WIDGET_VISIBLE (clist->vscrollbar))
        gtk_widget_show (clist->vscrollbar);
       
-      child_allocation.x = clist->internal_allocation.x + 
-       clist->internal_allocation.width -
-       clist->vscrollbar->requisition.width;
+      child_allocation.x = (clist->internal_allocation.x + 
+                           clist->internal_allocation.width -
+                           clist->vscrollbar->requisition.width);
       child_allocation.y = clist->internal_allocation.y;
       child_allocation.width = clist->vscrollbar->requisition.width;
       child_allocation.height = MAX (1, clist->internal_allocation.height -
-       (hscrollbar_vis ? (clist->hscrollbar->requisition.height + SCROLLBAR_SPACING (clist)) : 0));
-      
+                                    (hscrollbar_vis ?
+                                     (clist->hscrollbar->requisition.height +
+                                      SCROLLBAR_SPACING (clist)) : 0));
       gtk_widget_size_allocate (clist->vscrollbar, &child_allocation);
     }
   else
@@ -3419,11 +3554,13 @@ gtk_clist_size_allocate (GtkWidget * widget,
        gtk_widget_show (clist->hscrollbar);
       
       child_allocation.x = clist->internal_allocation.x;
-      child_allocation.y = clist->internal_allocation.y +
-       clist->internal_allocation.height -
-       clist->hscrollbar->requisition.height;
+      child_allocation.y = (clist->internal_allocation.y +
+                           clist->internal_allocation.height -
+                           clist->hscrollbar->requisition.height);
       child_allocation.width = MAX (1, clist->internal_allocation.width -
-       (vscrollbar_vis ? (clist->vscrollbar->requisition.width + SCROLLBAR_SPACING (clist)) : 0));
+                                   (vscrollbar_vis ?
+                                    (clist->vscrollbar->requisition.width +
+                                     SCROLLBAR_SPACING (clist)) : 0));
       child_allocation.height = clist->hscrollbar->requisition.height;
       
       gtk_widget_size_allocate (clist->hscrollbar, &child_allocation);
@@ -3639,6 +3776,9 @@ draw_row (GtkCList * clist,
   /* iterate and draw all the columns (row cells) and draw their contents */
   for (i = 0; i < clist->columns; i++)
     {
+      if (!clist->column[i].visible)
+       continue;
+
       clip_rectangle.x = clist->column[i].area.x + clist->hoffset;
       clip_rectangle.width = clist->column[i].area.width;
 
@@ -3930,9 +4070,10 @@ draw_rows (GtkCList * clist,
 static void
 size_allocate_title_buttons (GtkCList * clist)
 {
-  gint i, last_button = 0;
   GtkAllocation button_allocation;
-  gint visible_columns = clist->columns;
+  gint last_column;
+  gint last_button = 0;
+  gint i;
 
   if (!GTK_WIDGET_REALIZED (clist))
     return;
@@ -3942,91 +4083,100 @@ size_allocate_title_buttons (GtkCList * clist)
   button_allocation.width = 0;
   button_allocation.height = clist->column_title_area.height;
 
-  for (i = clist->columns-1; i > 0; i--)
-    if (!clist->column[i].visible)
-      visible_columns = i;
-    else
+  /* find last visible column */
+  for (last_column = clist->columns - 1; last_column >= 0; last_column--)
+    if (clist->column[last_column].visible)
       break;
 
-  for (i = 0; i < visible_columns; i++)
+  for (i = 0; i < last_column; i++)
     {
-      button_allocation.width += clist->column[i].area.width;
+      if (!clist->column[i].visible)
+       {
+         last_button = i + 1;
+         gdk_window_hide (clist->column[i].window);
+         continue;
+       }
 
-      if (i == visible_columns - 1)
-       button_allocation.width += 2 * (CELL_SPACING + COLUMN_INSET);
-      else if (clist->column[i].visible)
-       button_allocation.width += CELL_SPACING + (2 * COLUMN_INSET);
+      button_allocation.width += (clist->column[i].area.width +
+                                 CELL_SPACING + 2 * COLUMN_INSET);
 
-      if (i == (visible_columns - 1) || clist->column[i + 1].button)
+      if (!clist->column[i + 1].button)
        {
-         gtk_widget_size_allocate (clist->column[last_button].button, &button_allocation);
-         button_allocation.x += button_allocation.width;
-         button_allocation.width = 0;
+         gdk_window_hide (clist->column[i].window);
+         continue;
+       }
+
+      gtk_widget_size_allocate (clist->column[last_button].button,
+                               &button_allocation);
+      button_allocation.x += button_allocation.width;
+      button_allocation.width = 0;
 
+      if (clist->column[last_button].resizeable)
+       {
          gdk_window_show (clist->column[last_button].window);
          gdk_window_move_resize (clist->column[last_button].window,
                                  button_allocation.x - (DRAG_WIDTH / 2), 
-                                 0, DRAG_WIDTH, clist->column_title_area.height);
-         
-         last_button = i + 1;
+                                 0, DRAG_WIDTH,
+                                 clist->column_title_area.height);
        }
       else
-       {
-         gdk_window_hide (clist->column[i].window);
-       }
+       gdk_window_hide (clist->column[last_button].window);
+
+      last_button = i + 1;
+    }
+
+  button_allocation.width += (clist->column[last_column].area.width +
+                             2 * (CELL_SPACING + COLUMN_INSET));
+  gtk_widget_size_allocate (clist->column[last_button].button,
+                           &button_allocation);
+
+  if (clist->column[last_button].resizeable)
+    {
+      button_allocation.x += button_allocation.width;
+
+      gdk_window_show (clist->column[last_button].window);
+      gdk_window_move_resize (clist->column[last_button].window,
+                             button_allocation.x - (DRAG_WIDTH / 2), 
+                             0, DRAG_WIDTH, clist->column_title_area.height);
     }
+  else
+    gdk_window_hide (clist->column[last_button].window);
 }
 
 static void
 size_allocate_columns (GtkCList * clist)
 {
-  gint i, xoffset = 0;
-  gint visible_columns = clist->columns;
-
-  for (i = visible_columns-1; i > 0; i--)
-    if (!clist->column[i].visible)
-      visible_columns = i;
-    else
-      break;
-
-  for (i = 0; i < visible_columns; i++)
-    {
-      clist->column[i].area.x = xoffset + CELL_SPACING + COLUMN_INSET;
-
-      if (i == visible_columns - 1)
-       {
-         gint width;
+  gint xoffset = CELL_SPACING + COLUMN_INSET;
+  gint last_column;
+  gint width = 0;
+  gint i;
 
-         if (clist->column[i].width_set)
-           {
-             width = clist->column[i].width;
-           }
-         else
-           {
-             if (clist->column[i].title)
-               width = gdk_string_width (GTK_WIDGET (clist)->style->font, 
-                                         clist->column[i].title);
-             else
-               width = 0;
-           }
+  /* find last visible column and calculate correct column width */
+  for (last_column = clist->columns - 1;
+       last_column >= 0 && !clist->column[last_column].visible; last_column--);
 
-         clist->column[i].area.width = MAX (width,
-                                            clist->clist_window_width -
-                                            xoffset - (2 * (CELL_SPACING + COLUMN_INSET)));
-                                           
-       }
-      else
-       {
-         clist->column[i].area.width = clist->column[i].width;
-       }
+  if (last_column < 0)
+    return;
 
-      if (clist->column[i].visible)
-       xoffset += clist->column[i].area.width +
-         CELL_SPACING + (2 * COLUMN_INSET);
+  for (i = 0; i < last_column; i++)
+    {
+      if (!clist->column[i].visible)
+       continue;
+      clist->column[i].area.x = xoffset;
+      clist->column[i].area.width = clist->column[i].width;
+      xoffset += clist->column[i].width + CELL_SPACING + (2 * COLUMN_INSET);
     }
 
-  for (i = visible_columns; i < clist->columns; i++)
-    clist->column[i].area.width = 0;
+  if (clist->column[i].width_set)
+    width = clist->column[i].width;
+  else if (clist->column[i].title)
+    width = gdk_string_width (GTK_WIDGET (clist)->style->font,
+                             clist->column[i].title);
+
+  clist->column[i].area.x = xoffset;
+  clist->column[i].area.width = MAX (width,
+                                    clist->clist_window_width - xoffset -
+                                    (CELL_SPACING + COLUMN_INSET));
 }
 
 /*
@@ -4234,58 +4384,58 @@ static void
 draw_xor_line (GtkCList * clist)
 {
   GtkWidget *widget;
-  
+
   g_return_if_fail (clist != NULL);
-  
+
   widget = GTK_WIDGET (clist);
 
-  gdk_draw_line (widget->window, clist->xor_gc,  
-                 clist->x_drag,                                       
-                 widget->style->klass->ythickness,                               
-                 clist->x_drag,                                             
-                 clist->column_title_area.height + clist->clist_window_height + 1);
+  gdk_draw_line (widget->window, clist->xor_gc,
+                 clist->x_drag,
+                widget->style->klass->ythickness,
+                 clist->x_drag,
+                 clist->column_title_area.height +
+                clist->clist_window_height + 1);
 }
 
 /* this function returns the new width of the column being resized given
  * the column and x position of the cursor; the x cursor position is passed
  * in as a pointer and automagicly corrected if it's beyond min/max limits */
 static gint
-new_column_width (GtkCList * clist,
-                 gint column,
-                 gint * x,
-                 gint * visible)
+new_column_width (GtkCList *clist,
+                 gint      column,
+                 gint     *x)
 {
-  gint cx, rx, width;
-
-  cx = *x;
+  gint xthickness = GTK_WIDGET (clist)->style->klass->xthickness;
+  gint width;
+  gint cx;
+  gint dx;
 
   /* first translate the x position from widget->window
    * to clist->clist_window */
-  cx -= GTK_WIDGET (clist)->style->klass->xthickness;
+  cx = *x - xthickness;
 
-  /* rx is x from the list beginning */
-  rx = cx - clist->hoffset;
+  /* calculate new column width making sure it doesn't end up
+   * less than the minimum width */
+  dx = (COLUMN_LEFT_XPIXEL (clist, column) + COLUMN_INSET +
+       (column < clist->columns - 1) * CELL_SPACING);
+  width = cx - dx;
 
-  /* you can't shrink a column to less than its minimum width */
-  if (cx < (COLUMN_LEFT_XPIXEL (clist, column) + CELL_SPACING + COLUMN_INSET + COLUMN_MIN_WIDTH))
+  if (width < MAX (COLUMN_MIN_WIDTH, clist->column[column].min_width))
     {
-      *x = cx = COLUMN_LEFT_XPIXEL (clist, column) + CELL_SPACING + COLUMN_INSET + COLUMN_MIN_WIDTH +
-       GTK_WIDGET (clist)->style->klass->xthickness;
-      cx -= GTK_WIDGET (clist)->style->klass->xthickness;
-      rx = cx - clist->hoffset;
+      width = MAX (COLUMN_MIN_WIDTH, clist->column[column].min_width);
+      cx = dx + width;
+      *x = cx + xthickness;
     }
+  else if (clist->column[column].max_width >= COLUMN_MIN_WIDTH &&
+          width > clist->column[column].max_width)
+    {
+      width = clist->column[column].max_width;
+      cx = dx + clist->column[column].max_width;
+      *x = cx + xthickness;
+    }      
 
   if (cx < 0 || cx > clist->clist_window_width)
-    *visible = 0;
-  else
-    *visible = 1;
-
-  /* calculate new column width making sure it doesn't end up
-   * less than the minimum width */
-  width = (rx - COLUMN_LEFT (clist, column)) - COLUMN_INSET -
-    ((clist->columns == (column - 1)) ? CELL_SPACING : 0);
-  if (width < COLUMN_MIN_WIDTH)
-    width = COLUMN_MIN_WIDTH;
+    *x = -1;
 
   return width;
 }
@@ -4787,8 +4937,11 @@ columns_new (GtkCList * clist)
       column[i].button = NULL;
       column[i].window = NULL;
       column[i].width = 0;
-      column[i].visible = 1;
+      column[i].min_width = -1;
+      column[i].max_width = -1;
+      column[i].visible = TRUE;
       column[i].width_set = FALSE;
+      column[i].resizeable = TRUE;
       column[i].justification = GTK_JUSTIFY_LEFT;
     }
 
index bfa4bbabeb05be8269db936f1cd181f44737b421..3d2e70466aefb53d55d2381ae1743b4537f35024 100644 (file)
@@ -192,60 +192,63 @@ struct _GtkCListClass
 {
   GtkContainerClass parent_class;
   
-  void   (*select_row)          (GtkCList     *clist,
-                                gint          row,
-                                gint          column,
-                                GdkEvent     *event);
-  void   (*unselect_row)        (GtkCList     *clist,
-                                gint          row,
-                                gint          column,
-                                GdkEvent     *event);
-  void   (*click_column)        (GtkCList     *clist,
-                                gint          column);
-  void   (*toggle_focus_row)    (GtkCList     *clist);
-  void   (*select_all)          (GtkCList     *clist);
-  void   (*unselect_all)        (GtkCList     *clist);
-  void   (*undo_selection)      (GtkCList     *clist);
-  void   (*start_selection)     (GtkCList     *clist);
-  void   (*end_selection)       (GtkCList     *clist);
-  void   (*extend_selection)    (GtkCList     *clist,
-                                GtkScrollType scroll_type,
-                                gfloat        position,
-                                gboolean      auto_start_selection);
-  void   (*scroll_horizontal)   (GtkCList     *clist,
-                                GtkScrollType scroll_type,
-                                gfloat        position);
-  void   (*scroll_vertical)     (GtkCList     *clist,
-                                GtkScrollType scroll_type,
-                                gfloat        position);
-  void   (*toggle_add_mode)     (GtkCList     *clist);
-  void   (*abort_column_resize) (GtkCList     *clist);
-  void   (*resync_selection)    (GtkCList     *clist,
-                                GdkEvent     *event);
-  GList* (*selection_find)      (GtkCList     *clist,
-                                gint          row_number,
-                                GList        *row_list_element);
-  void   (*draw_row)            (GtkCList     *clist,
-                                GdkRectangle *area,
-                                gint          row,
-                                GtkCListRow  *clist_row);
-  void   (*clear)               (GtkCList     *clist);
-  void   (*fake_unselect_all)   (GtkCList     *clist,
-                                gint          row);
-  void   (*sort_list)           (GtkCList     *clist);
-  gint   (*insert_row)          (GtkCList     *clist,
-                                gint          row,
-                                gchar       *text[]);
-  void   (*remove_row)          (GtkCList    *clist,
-                                gint         row);
-  void   (*set_cell_contents)   (GtkCList    *clist,
-                                GtkCListRow *clist_row,
-                                gint         column,
-                                GtkCellType  type,
-                                const gchar *text,
-                                guint8       spacing,
-                                GdkPixmap   *pixmap,
-                                GdkBitmap   *mask);
+  void   (*select_row)          (GtkCList      *clist,
+                                gint           row,
+                                gint           column,
+                                GdkEvent      *event);
+  void   (*unselect_row)        (GtkCList      *clist,
+                                gint           row,
+                                gint           column,
+                                GdkEvent      *event);
+  void   (*click_column)        (GtkCList      *clist,
+                                gint           column);
+  void   (*resize_column)       (GtkCList      *clist,
+                                gint           column,
+                                 gint           width);
+  void   (*toggle_focus_row)    (GtkCList      *clist);
+  void   (*select_all)          (GtkCList      *clist);
+  void   (*unselect_all)        (GtkCList      *clist);
+  void   (*undo_selection)      (GtkCList      *clist);
+  void   (*start_selection)     (GtkCList      *clist);
+  void   (*end_selection)       (GtkCList      *clist);
+  void   (*extend_selection)    (GtkCList      *clist,
+                                GtkScrollType  scroll_type,
+                                gfloat         position,
+                                gboolean       auto_start_selection);
+  void   (*scroll_horizontal)   (GtkCList      *clist,
+                                GtkScrollType  scroll_type,
+                                gfloat         position);
+  void   (*scroll_vertical)     (GtkCList      *clist,
+                                GtkScrollType  scroll_type,
+                                gfloat         position);
+  void   (*toggle_add_mode)     (GtkCList      *clist);
+  void   (*abort_column_resize) (GtkCList      *clist);
+  void   (*resync_selection)    (GtkCList      *clist,
+                                GdkEvent      *event);
+  GList* (*selection_find)      (GtkCList      *clist,
+                                gint           row_number,
+                                GList         *row_list_element);
+  void   (*draw_row)            (GtkCList      *clist,
+                                GdkRectangle  *area,
+                                gint           row,
+                                GtkCListRow   *clist_row);
+  void   (*clear)               (GtkCList      *clist);
+  void   (*fake_unselect_all)   (GtkCList      *clist,
+                                gint           row);
+  void   (*sort_list)           (GtkCList      *clist);
+  gint   (*insert_row)          (GtkCList      *clist,
+                                gint           row,
+                                gchar         *text[]);
+  void   (*remove_row)          (GtkCList      *clist,
+                                gint           row);
+  void   (*set_cell_contents)   (GtkCList      *clist,
+                                GtkCListRow   *clist_row,
+                                gint           column,
+                                GtkCellType    type,
+                                const gchar   *text,
+                                guint8         spacing,
+                                GdkPixmap     *pixmap,
+                                GdkBitmap     *mask);
   
   gint scrollbar_spacing;
 };
@@ -259,10 +262,13 @@ struct _GtkCListColumn
   GdkWindow *window;
   
   gint width;
+  gint min_width;
+  gint max_width;
   GtkJustification justification;
   
-  gint visible : 1;  
-  gint width_set : 1;
+  gint visible    : 1;  
+  gint width_set  : 1;
+  gint resizeable : 1;
 };
 
 struct _GtkCListRow
@@ -357,7 +363,7 @@ GtkType gtk_clist_get_type (void);
 /* constructers useful for gtk-- wrappers */
 void gtk_clist_construct (GtkCList *clist,
                          gint      columns,
-                         gchar   *titles[]);
+                         gchar    *titles[]);
 
 /* create a new GtkCList */
 GtkWidget *gtk_clist_new             (gint   columns);
@@ -365,24 +371,24 @@ GtkWidget *gtk_clist_new_with_titles (gint   columns,
                                      gchar *titles[]);
 
 /* set the border style of the clist */
-void gtk_clist_set_border (GtkCList     *clist,
-                          GtkShadowType border);
+void gtk_clist_set_border (GtkCList      *clist,
+                          GtkShadowType  border);
 
 /* set the clist's selection mode */
-void gtk_clist_set_selection_mode (GtkCList        *clist,
-                                  GtkSelectionMode mode);
+void gtk_clist_set_selection_mode (GtkCList         *clist,
+                                  GtkSelectionMode  mode);
 
 /* set policy on the scrollbar, to either show them all the time
- * or show them only when they are needed, ie., when there is more than one page
- * of information
+ * or show them only when they are needed, ie., when there is more
+ * than one page of information
  */
-void gtk_clist_set_policy (GtkCList     *clist,
-                          GtkPolicyType vscrollbar_policy,
-                          GtkPolicyType hscrollbar_policy);
+void gtk_clist_set_policy (GtkCList      *clist,
+                          GtkPolicyType  vscrollbar_policy,
+                          GtkPolicyType  hscrollbar_policy);
 
-/* freeze all visual updates of the list, and then thaw the list after you have made
- * a number of changes and the updates wil occure in a more efficent mannor than if
- * you made them on a unfrozen list
+/* freeze all visual updates of the list, and then thaw the list after
+ * you have made a number of changes and the updates wil occure in a
+ * more efficent mannor than if you made them on a unfrozen list
  */
 void gtk_clist_freeze (GtkCList *clist);
 void gtk_clist_thaw   (GtkCList *clist);
@@ -402,11 +408,6 @@ void gtk_clist_column_title_passive  (GtkCList *clist,
 void gtk_clist_column_titles_active  (GtkCList *clist);
 void gtk_clist_column_titles_passive (GtkCList *clist);
 
-/* set visibility of a column */
-void gtk_clist_set_column_visibility (GtkCList *clist,
-                                     gint      column,
-                                     gint      visible);
-
 /* set the title in the column title button */
 void gtk_clist_set_column_title (GtkCList    *clist,
                                 gint         column,
@@ -418,9 +419,19 @@ void gtk_clist_set_column_widget (GtkCList  *clist,
                                  GtkWidget *widget);
 
 /* set the justification on a column */
-void gtk_clist_set_column_justification (GtkCList        *clist,
-                                        gint             column,
-                                        GtkJustification justification);
+void gtk_clist_set_column_justification (GtkCList         *clist,
+                                        gint              column,
+                                        GtkJustification  justification);
+
+/* set visibility of a column */
+void gtk_clist_set_column_visibility (GtkCList *clist,
+                                     gint      column,
+                                     gboolean  visible);
+
+/* enable/disable column resize operations by mouse */
+void gtk_clist_set_column_resizeable (GtkCList *clist,
+                                     gint      column,
+                                     gboolean  resizeable);
 
 /* set the pixel width of a column; this is a necessary step in
  * creating a CList because otherwise the column width is chozen from
@@ -430,17 +441,24 @@ void gtk_clist_set_column_width (GtkCList *clist,
                                 gint      column,
                                 gint      width);
 
+/* set column minimum/maximum width. min/max_width < 0 => no restriction */
+void gtk_clist_set_column_min_width (GtkCList *clist,
+                                    gint      column,
+                                    gint      min_width);
+void gtk_clist_set_column_max_width (GtkCList *clist,
+                                    gint      column,
+                                    gint      max_width);
+
 /* change the height of the rows, the default is the hight
  * of the current font
  */
 void gtk_clist_set_row_height (GtkCList *clist,
                               gint      height);
 
-/* scroll the viewing area of the list to the given column
- * and row; row_align and col_align are between 0-1 representing the
- * location the row should appear on the screnn, 0.0 being top or left,
- * 1.0 being bottom or right; if row or column is -1 then then there
- * is no change
+/* scroll the viewing area of the list to the given column and row;
+ * row_align and col_align are between 0-1 representing the location the
+ * row should appear on the screnn, 0.0 being top or left, 1.0 being
+ * bottom or right; if row or column is -1 then then there is no change
  */
 void gtk_clist_moveto (GtkCList *clist,
                       gint      row,
@@ -466,10 +484,10 @@ void gtk_clist_set_text (GtkCList    *clist,
 /* for the "get" functions, any of the return pointer can be
  * NULL if you are not interested
  */
-gint gtk_clist_get_text (GtkCList *clist,
-                        gint      row,
-                        gint      column,
-                        gchar   **text);
+gint gtk_clist_get_text (GtkCList  *clist,
+                        gint       row,
+                        gint       column,
+                        gchar    **text);
 
 /* sets a given cell's pixmap, replacing it's current contents */
 void gtk_clist_set_pixmap (GtkCList  *clist,
@@ -493,13 +511,13 @@ void gtk_clist_set_pixtext (GtkCList    *clist,
                            GdkPixmap   *pixmap,
                            GdkBitmap   *mask);
 
-gint gtk_clist_get_pixtext (GtkCList    *clist,
-                           gint         row,
-                           gint         column,
-                           gchar      **text,
-                           guint8      *spacing,
-                           GdkPixmap  **pixmap,
-                           GdkBitmap  **mask);
+gint gtk_clist_get_pixtext (GtkCList   *clist,
+                           gint        row,
+                           gint        column,
+                           gchar     **text,
+                           guint8     *spacing,
+                           GdkPixmap **pixmap,
+                           GdkBitmap **mask);
 
 /* sets the foreground color of a row, the colar must already
  * be allocated
@@ -516,8 +534,8 @@ void gtk_clist_set_background (GtkCList *clist,
                               GdkColor *color);
 
 /* this sets a horizontal and vertical shift for drawing
- * the contents of a cell; it can be positive or negitive; this is
- * particulary useful for indenting items in a column
+ * the contents of a cell; it can be positive or negitive;
+ * this is particulary useful for indenting items in a column
  */
 void gtk_clist_set_shift (GtkCList *clist,
                          gint      row,
@@ -540,8 +558,8 @@ gint gtk_clist_prepend (GtkCList *clist,
 gint gtk_clist_append  (GtkCList *clist,
                        gchar    *text[]);
 
-/* inserts a row at index row and returns the row where it was actually
- * inserted (may be different from "row" in auto_sort mode)
+/* inserts a row at index row and returns the row where it was
+ * actually inserted (may be different from "row" in auto_sort mode)
  */
 gint gtk_clist_insert (GtkCList *clist,
                       gint      row,
@@ -557,10 +575,10 @@ void gtk_clist_set_row_data (GtkCList *clist,
                             gpointer  data);
 
 /* sets a data pointer for a given row with destroy notification */
-void gtk_clist_set_row_data_full (GtkCList        *clist,
-                                 gint             row,
-                                 gpointer         data,
-                                 GtkDestroyNotify destroy);
+void gtk_clist_set_row_data_full (GtkCList         *clist,
+                                 gint              row,
+                                 gpointer          data,
+                                 GtkDestroyNotify  destroy);
 
 /* returns the data set for a row */
 gpointer gtk_clist_get_row_data (GtkCList *clist,
@@ -585,8 +603,8 @@ void gtk_clist_unselect_row (GtkCList *clist,
 /* undo the last select/unselect operation */
 void gtk_clist_undo_selection (GtkCList *clist);
 
-/* clear the entire list -- this is much faster than removing each item 
- * with gtk_clist_remove
+/* clear the entire list -- this is much faster than removing
+ * each item with gtk_clist_remove
  */
 void gtk_clist_clear (GtkCList *clist);
 
@@ -617,8 +635,8 @@ void gtk_clist_set_sort_column (GtkCList *clist,
                                gint      column);
 
 /* how to sort : ascending or descending */
-void gtk_clist_set_sort_type (GtkCList   *clist,
-                             GtkSortType sort_type);
+void gtk_clist_set_sort_type (GtkCList    *clist,
+                             GtkSortType  sort_type);
 
 /* sort the list with the current compare function */
 void gtk_clist_sort (GtkCList *clist);
index 5e666b389cecaa7892e9f33323967ec4001332d4..b7448ecf559a62afb30beeef51ec0e67cac2c75f 100644 (file)
@@ -969,37 +969,41 @@ draw_xor_line (GtkCTree *ctree)
   else 
     y = ROW_TOP_YPIXEL (clist, ctree->drag_row) - 1;
 
-  switch (clist->column[ctree->tree_column].justification)
-    {
-    case GTK_JUSTIFY_CENTER:
-    case GTK_JUSTIFY_FILL:
-    case GTK_JUSTIFY_LEFT:
-      if (ctree->tree_column > 0)
-       gdk_draw_line (clist->clist_window, ctree->xor_gc, 
-                      COLUMN_LEFT_XPIXEL(clist, 0), y,
-                      COLUMN_LEFT_XPIXEL(clist, ctree->tree_column - 1) +
-                      clist->column[ctree->tree_column - 1].area.width, y);
+  if (clist->column[ctree->tree_column].visible)
+    switch (clist->column[ctree->tree_column].justification)
+      {
+      case GTK_JUSTIFY_CENTER:
+      case GTK_JUSTIFY_FILL:
+      case GTK_JUSTIFY_LEFT:
+       if (ctree->tree_column > 0)
+         gdk_draw_line (clist->clist_window, ctree->xor_gc, 
+                        COLUMN_LEFT_XPIXEL(clist, 0), y,
+                        COLUMN_LEFT_XPIXEL(clist, ctree->tree_column - 1) +
+                        clist->column[ctree->tree_column - 1].area.width, y);
       
-      gdk_draw_line (clist->clist_window, ctree->xor_gc, 
-                    COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + 
-                    ctree->tree_indent * level -
-                    (ctree->tree_indent - PM_SIZE) / 2, y,
-                    GTK_WIDGET (ctree)->allocation.width, y);
-      break;
-    case GTK_JUSTIFY_RIGHT:
-      if (ctree->tree_column < clist->columns - 1)
        gdk_draw_line (clist->clist_window, ctree->xor_gc, 
-                      COLUMN_LEFT_XPIXEL(clist, ctree->tree_column + 1), y,
-                      COLUMN_LEFT_XPIXEL(clist, clist->columns - 1) +
-                      clist->column[clist->columns - 1].area.width, y);
+                      COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + 
+                      ctree->tree_indent * level -
+                      (ctree->tree_indent - PM_SIZE) / 2, y,
+                      GTK_WIDGET (ctree)->allocation.width, y);
+       break;
+      case GTK_JUSTIFY_RIGHT:
+       if (ctree->tree_column < clist->columns - 1)
+         gdk_draw_line (clist->clist_window, ctree->xor_gc, 
+                        COLUMN_LEFT_XPIXEL(clist, ctree->tree_column + 1), y,
+                        COLUMN_LEFT_XPIXEL(clist, clist->columns - 1) +
+                        clist->column[clist->columns - 1].area.width, y);
       
-      gdk_draw_line (clist->clist_window, ctree->xor_gc, 
-                    0, y, COLUMN_LEFT_XPIXEL(clist, ctree->tree_column)
-                    + clist->column[ctree->tree_column].area.width
-                    - ctree->tree_indent * level +
-                    (ctree->tree_indent - PM_SIZE) / 2, y);
-      break;
-    }
+       gdk_draw_line (clist->clist_window, ctree->xor_gc, 
+                      0, y, COLUMN_LEFT_XPIXEL(clist, ctree->tree_column)
+                      + clist->column[ctree->tree_column].area.width -
+                      ctree->tree_indent * level +
+                      (ctree->tree_indent - PM_SIZE) / 2, y);
+       break;
+      }
+  else
+    gdk_draw_line (clist->clist_window, ctree->xor_gc, 
+                  0, y, clist->clist_window_width, y);
 }
 
 static void
@@ -1017,77 +1021,84 @@ draw_xor_rect (GtkCTree *ctree)
 
   y = ROW_TOP_YPIXEL (clist, ctree->drag_row) + clist->row_height;
 
-  switch (clist->column[ctree->tree_column].justification)
-    {
-    case GTK_JUSTIFY_CENTER:
-    case GTK_JUSTIFY_FILL:
-    case GTK_JUSTIFY_LEFT:
-      points[0].x =  COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + 
-       ctree->tree_indent * level - (ctree->tree_indent - PM_SIZE) / 2;
-      points[0].y = y;
-      points[3].x = points[0].x;
-      points[3].y = y - clist->row_height - 1;
-      points[1].x = clist->clist_window_width - 1;
-      points[1].y = points[0].y;
-      points[2].x = points[1].x;
-      points[2].y = points[3].y;
-
-      for (i = 0; i < 3; i++)
-       gdk_draw_line (clist->clist_window, ctree->xor_gc,
-                      points[i].x, points[i].y, points[i+1].x, points[i+1].y);
-
-      if (ctree->tree_column > 0)
-       {
-         points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column - 1) +
-           clist->column[ctree->tree_column - 1].area.width ;
-         points[0].y = y;
-         points[3].x = points[0].x;
-         points[3].y = y - clist->row_height - 1;
-         points[1].x = 0;
-         points[1].y = points[0].y;
-         points[2].x = 0;
-         points[2].y = points[3].y;
-
-         for (i = 0; i < 3; i++)
-           gdk_draw_line (clist->clist_window, ctree->xor_gc,
-                          points[i].x, points[i].y, points[i+1].x, 
-                          points[i+1].y);
-       }
-      break;
-    case GTK_JUSTIFY_RIGHT:
-      points[0].x =  COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) - 
-       ctree->tree_indent * level + (ctree->tree_indent - PM_SIZE) / 2  +
-       clist->column[ctree->tree_column].area.width;
-      points[0].y = y;
-      points[3].x = points[0].x;
-      points[3].y = y - clist->row_height - 1;
-      points[1].x = 0;
-      points[1].y = points[0].y;
-      points[2].x = 0;
-      points[2].y = points[3].y;
-
-      for (i = 0; i < 3; i++)
-       gdk_draw_line (clist->clist_window, ctree->xor_gc,
-                      points[i].x, points[i].y, points[i+1].x, points[i+1].y);
-
-      if (ctree->tree_column < clist->columns - 1)
-       {
-         points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column + 1);
-         points[0].y = y;
-         points[3].x = points[0].x;
-         points[3].y = y - clist->row_height - 1;
-         points[1].x = clist->clist_window_width - 1;
-         points[1].y = points[0].y;
-         points[2].x = points[1].x;
-         points[2].y = points[3].y;
-
-         for (i = 0; i < 3; i++)
-           gdk_draw_line (clist->clist_window, ctree->xor_gc,
-                          points[i].x, points[i].y, points[i+1].x, 
-                          points[i+1].y);
-       }
-      break;
-    }      
+  if (clist->column[ctree->tree_column].visible)
+    switch (clist->column[ctree->tree_column].justification)
+      {
+      case GTK_JUSTIFY_CENTER:
+      case GTK_JUSTIFY_FILL:
+      case GTK_JUSTIFY_LEFT:
+       points[0].x =  COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + 
+         ctree->tree_indent * level - (ctree->tree_indent - PM_SIZE) / 2;
+       points[0].y = y;
+       points[3].x = points[0].x;
+       points[3].y = y - clist->row_height - 1;
+       points[1].x = clist->clist_window_width - 1;
+       points[1].y = points[0].y;
+       points[2].x = points[1].x;
+       points[2].y = points[3].y;
+
+       for (i = 0; i < 3; i++)
+         gdk_draw_line (clist->clist_window, ctree->xor_gc,
+                        points[i].x, points[i].y,
+                        points[i+1].x, points[i+1].y);
+
+       if (ctree->tree_column > 0)
+         {
+           points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column - 1) +
+             clist->column[ctree->tree_column - 1].area.width ;
+           points[0].y = y;
+           points[3].x = points[0].x;
+           points[3].y = y - clist->row_height - 1;
+           points[1].x = 0;
+           points[1].y = points[0].y;
+           points[2].x = 0;
+           points[2].y = points[3].y;
+
+           for (i = 0; i < 3; i++)
+             gdk_draw_line (clist->clist_window, ctree->xor_gc,
+                            points[i].x, points[i].y, points[i+1].x, 
+                            points[i+1].y);
+         }
+       break;
+      case GTK_JUSTIFY_RIGHT:
+       points[0].x =  COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) - 
+         ctree->tree_indent * level + (ctree->tree_indent - PM_SIZE) / 2  +
+         clist->column[ctree->tree_column].area.width;
+       points[0].y = y;
+       points[3].x = points[0].x;
+       points[3].y = y - clist->row_height - 1;
+       points[1].x = 0;
+       points[1].y = points[0].y;
+       points[2].x = 0;
+       points[2].y = points[3].y;
+
+       for (i = 0; i < 3; i++)
+         gdk_draw_line (clist->clist_window, ctree->xor_gc,
+                        points[i].x, points[i].y,
+                        points[i+1].x, points[i+1].y);
+
+       if (ctree->tree_column < clist->columns - 1)
+         {
+           points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column + 1);
+           points[0].y = y;
+           points[3].x = points[0].x;
+           points[3].y = y - clist->row_height - 1;
+           points[1].x = clist->clist_window_width - 1;
+           points[1].y = points[0].y;
+           points[2].x = points[1].x;
+           points[2].y = points[3].y;
+
+           for (i = 0; i < 3; i++)
+             gdk_draw_line (clist->clist_window, ctree->xor_gc,
+                            points[i].x, points[i].y,
+                            points[i+1].x, points[i+1].y);
+         }
+       break;
+      }      
+  else
+    gdk_draw_rectangle (clist->clist_window, ctree->xor_gc, FALSE,
+                       0, y - clist->row_height,
+                       clist->clist_window_width - 1, clist->row_height);
 }
 
 static void
@@ -1266,6 +1277,8 @@ draw_row (GtkCList     *clist,
   /* iterate and draw all the columns (row cells) and draw their contents */
   for (i = 0; i < clist->columns; i++)
     {
+      if (!clist->column[i].visible)
+       continue;
        
       if (!need_redraw && ctree->tree_column != i)
        continue;
@@ -3678,6 +3691,9 @@ ctree_is_hot_spot (GtkCTree     *ctree,
   tree_row = GTK_CTREE_ROW (node);
   clist = GTK_CLIST (ctree);
 
+  if (!clist->column[ctree->tree_column].visible)
+    return FALSE;
+
   cell = GTK_CELL_PIXTEXT(tree_row->row.cell[ctree->tree_column]);
 
   yu = ROW_TOP_YPIXEL (clist, row) + (clist->row_height - PM_SIZE) / 2;
@@ -4321,6 +4337,40 @@ gtk_ctree_find_by_row_data (GtkCTree     *ctree,
   return NULL;
 }
 
+GList *
+gtk_ctree_find_all_by_row_data (GtkCTree     *ctree,
+                               GtkCTreeNode *node,
+                               gpointer      data)
+{
+  GList *list = NULL;
+
+  g_return_val_if_fail (ctree != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_CTREE (ctree), NULL);
+
+  /* if node == NULL then look in the whole tree */
+  if (!node)
+    node = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
+
+  while (node)
+    {
+      if (GTK_CTREE_ROW (node)->row.data == data)
+        list = g_list_append (list, node);
+
+      if (GTK_CTREE_ROW (node)->children)
+        {
+         GList *sub_list;
+
+          sub_list = gtk_ctree_find_all_by_row_data (ctree,
+                                                    GTK_CTREE_ROW
+                                                    (node)->children,
+                                                    data);
+          list = g_list_concat (list, sub_list);
+        }
+      node = GTK_CTREE_ROW (node)->sibling;
+    }
+  return list;
+}
+
 GtkCTreeNode *
 gtk_ctree_find_by_row_data_custom (GtkCTree     *ctree,
                                   GtkCTreeNode *node,
@@ -4347,6 +4397,43 @@ gtk_ctree_find_by_row_data_custom (GtkCTree     *ctree,
   return NULL;
 }
 
+GList *
+gtk_ctree_find_all_by_row_data_custom (GtkCTree     *ctree,
+                                      GtkCTreeNode *node,
+                                      gpointer      data,
+                                      GCompareFunc  func)
+{
+  GList *list = NULL;
+
+  g_return_val_if_fail (ctree != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_CTREE (ctree), NULL);
+  g_return_val_if_fail (func != NULL, NULL);
+
+  /* if node == NULL then look in the whole tree */
+  if (!node)
+    node = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
+
+  while (node)
+    {
+      if (!func (GTK_CTREE_ROW (node)->row.data, data))
+        list = g_list_append (list, node);
+
+      if (GTK_CTREE_ROW (node)->children)
+        {
+         GList *sub_list;
+
+          sub_list = gtk_ctree_find_all_by_row_data_custom (ctree,
+                                                           GTK_CTREE_ROW
+                                                           (node)->children,
+                                                           data,
+                                                           func);
+          list = g_list_concat (list, sub_list);
+        }
+      node = GTK_CTREE_ROW (node)->sibling;
+    }
+  return list;
+}
+
 gboolean
 gtk_ctree_is_hot_spot (GtkCTree *ctree, 
                       gint      x, 
index 2739fd755ca746ceaf5a3ff2e368cf1127e21059..b7e77600f1cd9b34d1b61a8c72cdac6355f4d5e1 100644 (file)
@@ -240,10 +240,19 @@ gboolean gtk_ctree_is_ancestor                   (GtkCTree     *ctree,
 GtkCTreeNode * gtk_ctree_find_by_row_data        (GtkCTree     *ctree,
                                                  GtkCTreeNode *node,
                                                  gpointer      data);
+/* returns a GList of all GtkCTreeNodes with row->data == data. */
+GList * gtk_ctree_find_all_by_row_data           (GtkCTree     *ctree,
+                                                 GtkCTreeNode *node,
+                                                 gpointer      data);
 GtkCTreeNode * gtk_ctree_find_by_row_data_custom (GtkCTree     *ctree,
                                                  GtkCTreeNode *node,
                                                  gpointer      data,
                                                  GCompareFunc  func);
+/* returns a GList of all GtkCTreeNodes with row->data == data. */
+GList * gtk_ctree_find_all_by_row_data_custom    (GtkCTree     *ctree,
+                                                 GtkCTreeNode *node,
+                                                 gpointer      data,
+                                                 GCompareFunc  func);
 gboolean gtk_ctree_is_hot_spot                   (GtkCTree     *ctree,
                                                  gint          x,
                                                  gint          y);